﻿using System;
using System.Linq;
using Eflong.Config;
using Eflong.Config.DataFilter;
using Eflong.KJFiles;
using Eflong.MonitoringLib.MonitoringUnit;

namespace Eflong.Convert
{
    public class Kj143FilesToMonitoring
    {
        /// <summary>
        /// 转换Kj43 文件内容到 Eflong 的测点定义与实时数据
        /// </summary>
        /// <param name="devFile"></param>
        /// <param name="coalMineUnit"></param>
        /// <param name="nSysNo"></param>
        /// <param name="sPostfix"></param>
        public static void Kj143FilesToCoalMineUnitManager( Kj143DevFiles devFile , ref BaseCoalMineUnit coalMineUnit , string sPostfix )
        {
            if ( devFile.AqMcFile.Changed )
            {
                devFile.AqMcFile.Changed = false;
                if ( devFile.AqMcFile.Items != null )
                {
                    foreach ( Kj143CommonItem devItem in devFile.AqMcFile.Items )
                    {
                        ConvertToMonitoringUnit( devItem , sPostfix , ref coalMineUnit );
                    }
                    devFile.DefinitionsChanged = true;
                }
            }
            if ( devFile.AqKcFile.Changed )
            {
                devFile.AqKcFile.Changed = false;
                if ( devFile.AqKcFile.Items != null )
                {
                    foreach ( Kj143CommonItem devItem in devFile.AqKcFile.Items )
                    {
                        ConvertToMonitoringUnit( devItem , sPostfix , ref coalMineUnit );
                    }
                    devFile.DefinitionsChanged = true;
                }
            }
        }

        private static void ConvertToMonitoringUnit( Kj143CommonItem devItem , string sPostfix , ref BaseCoalMineUnit coalMineUnit )
        {
            string sId = GetSensorId( devItem ) + sPostfix;

            #region 过滤测点

            if ( DataFilter( sId.ToLower( ) , devItem.Location.ToLower( ) ) ) return;

            #endregion 过滤测点

            BaseMonitoringUnit monitoringUint = coalMineUnit.GetMonitoringUnit( sId );
            if ( monitoringUint == null )
            {
                monitoringUint = new BaseMonitoringUnit { nSysNo = ( int )coalMineUnit.m_nId , m_strId = sId };
                coalMineUnit.AddMonitoringUnit( monitoringUint );
            }
            ConvertDevItemToMonitoringUnit( devItem , ref monitoringUint , sPostfix );
        }

        /// <summary>
        ///4884;0000004732;
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        private static string GetSensorId( string fNo , string sNo )
        {
            return fNo + sNo.Substring( 5 , 4 );
        }

        private static string GetSensorId( Kj143CommonItem item )
        {
            return item.FzNo + item.No.Substring( 6 , 4 );
        }

        /// <summary>
        /// 实现监测系统的测点定义向Eflong的联网系统的测点定义转换
        /// </summary>
        /// <param name="devItem"></param>
        /// <param name="monitoringUint"></param>
        public static void ConvertDevItemToMonitoringUnit( Kj143CommonItem devItem , ref BaseMonitoringUnit monitoringUint , string sPostfix )
        {
            string sName = "" , sUnit = "" , sType = string.Empty;
            MonitoringUnitType.SensorTypes sensorType = MonitoringUnitType.SensorTypes.模拟量;
            switch ( devItem.SensorType )
            {
                case Kj143SensorTypes.模拟量:
                    sensorType = MonitoringUnitType.SensorTypes.模拟量;
                    sName = ( ( Kj143CommonItem.Kj143AnalogTypes )devItem.NSensorType ).ToString( );
                    sUnit = devItem.Unit;
                    sType = "模拟量";
                    break;

                case Kj143SensorTypes.开关量:
                    sensorType = MonitoringUnitType.SensorTypes.开关量;
                    sType = "开关量";
                    sName = ( ( Kj143CommonItem.Kj143DigitalTypes )devItem.NSensorType ).ToString( );
                    break;

                case Kj143SensorTypes.累计量:
                    sensorType = MonitoringUnitType.SensorTypes.累计量;
                    sType = "累计量";
                    sName = ( ( Kj143CommonItem.Kj143AddupTypes )devItem.NSensorType ).ToString( );
                    sUnit = devItem.Unit;
                    break;

                default:
                    sensorType = MonitoringUnitType.SensorTypes.模拟量;
                    sName = "模拟量";
                    break;
            }
            monitoringUint.m_strId = GetSensorId( devItem ) + sPostfix;

            monitoringUint.m_strName = devItem.Location;
            ConvertLimitType( ref devItem , ref sName , monitoringUint.m_strId );
            monitoringUint.m_Type = MonitoringUnitType.GetConvertType( sType , sName , sUnit , ref monitoringUint , ref sensorType );
            ConvertUnit( ref monitoringUint );
            if ( sensorType == MonitoringUnitType.SensorTypes.模拟量 )
            {
                Kj143AqMcItem aqMcItem = ( Kj143AqMcItem )devItem;
                monitoringUint.m_Modality = MonitoringUnitModality.Modalities.Analog;

                monitoringUint.m_fLowerBound = aqMcItem.LowValue;
                monitoringUint.m_fUpperBound = aqMcItem.HighValue;
                monitoringUint.m_fLowerLimit = ( aqMcItem.LowValue );
                monitoringUint.m_fUpperLimit = ( aqMcItem.AlarmLimit );
                monitoringUint.m_fBreakLimit = ( aqMcItem.PowerOffLimit );
                monitoringUint.m_fRestLimit = ( aqMcItem.PowertOnLimit );
                if ( monitoringUint.m_Type == MonitoringUnitType.Types.瓦斯 && monitoringUint.m_fUpperBound > 40 && monitoringUint.m_fBreakLimit > 2.5 )
                {
                    //"高浓瓦斯";
                    monitoringUint.m_Type = MonitoringUnitType.Types.高浓瓦斯;
                }
                if ( monitoringUint.m_Type == MonitoringUnitType.Types.高浓瓦斯 && monitoringUint.m_fBreakLimit <= 2.5 )
                {
                    //"高浓瓦斯";
                    monitoringUint.m_Type = MonitoringUnitType.Types.瓦斯;
                    float upperLimit = ( aqMcItem.AlarmLimit );

                    if ( KJXX_Files.IsStartandAlarmLimit )
                    {
                        if ( upperLimit <= 0.5 )
                        {
                            upperLimit = 0.5f;
                        }
                        else if ( upperLimit > 0.5 && upperLimit <= 0.7 )
                        {
                            upperLimit = 0.7f;
                        }
                        else if ( upperLimit > 0.7 && upperLimit <= 0.75 )
                        {
                            upperLimit = 0.75f;
                        }
                        else if ( upperLimit > 0.75 && upperLimit <= 1.0 )
                        {
                            upperLimit = 1.00f;
                        }
                        else if ( upperLimit > 1.0 && upperLimit <= 1.50 )
                        {
                            upperLimit = 1.5f;
                        }

                        else if ( upperLimit > 1.5 && upperLimit < 4.00 )
                        {
                            upperLimit = 2.5f;
                        }
                    }
                    monitoringUint.m_fUpperLimit = upperLimit;

                    float fBreak = aqMcItem.PowerOffLimit;
                    float fRest = ( aqMcItem.PowertOnLimit );

                    if ( fBreak < upperLimit && fBreak >= 0.5 )
                    {
                        // 如果断电值小于报警值,则取报警值为断电值
                        upperLimit = fBreak;
                    }
                    if ( fRest > upperLimit )
                    {
                        fRest = upperLimit;
                    }

                    // 1,102,1#联络巷风机吸风口甲烷<109*NULL>,10,1,%,0,100,0,0.40,0.40,0.39
                    // 1,103,151012巷开拓面甲烷<109*NULL>,10,1,%,0,100,0,0.80,1.30,0.80
                    if ( fBreak >= 0.8 && fBreak <= 1.0 )
                    {
                        fBreak = 1.00f;
                    }
                    if ( fBreak > 1.1 && fBreak <= 1.50 )
                    {
                        fBreak = 1.5f;
                    }
                    monitoringUint.m_fBreakLimit = fBreak;
                    monitoringUint.m_fRestLimit = fRest;
                }
            }
            else if ( sensorType == MonitoringUnitType.SensorTypes.开关量 || sensorType == MonitoringUnitType.SensorTypes.控制量 )
            {
                monitoringUint.m_Modality = MonitoringUnitModality.Modalities.Digital;
            }
            else
            {
                if ( monitoringUint.m_strUnit != "" )
                {
                    monitoringUint.m_Modality = MonitoringUnitModality.Modalities.Analog;
                    Kj143AqMcItem aqMcItem = ( Kj143AqMcItem )devItem;
                    monitoringUint.m_fLowerBound = aqMcItem.LowValue;
                    monitoringUint.m_fUpperBound = aqMcItem.HighValue;
                }
                else
                {
                    monitoringUint.m_Modality = MonitoringUnitModality.Modalities.Digital;
                }
            }
            ConvertLimitSet( ref monitoringUint );
        }

        public static void KJXXN_RtDataFileToCoalMineUnitManager( Kj143RtData rtData , ref BaseCoalMineUnit coalMineUnit , string sPostfix )
        {
            if ( rtData.AqSsFile.Changed )
            {
                rtData.AqSsFile.Changed = false;
                if ( rtData.AqSsFile.Items != null )
                {
                    foreach ( Kj143AqSsItem dataItem in rtData.AqSsFile.Items )
                    {
                        string sId = GetSensorId( dataItem ) + sPostfix;

                        BaseMonitoringUnit monitoringUint = coalMineUnit.GetMonitoringUnit( sId );
                        if ( monitoringUint != null )
                        {
                            if ( monitoringUint.m_Modality == MonitoringUnitModality.Modalities.Digital )
                            {
                                string type = monitoringUint.m_Type.ToString( );
                                DigitalState digitalState = rtData.devFile.GetDigitalState( type );
                                if ( !digitalState.bState0 )
                                {
                                    //Eflong  0 正常， 1 异常
                                    // Kj143  // 0 停， 1开
                                }
                                ConvertRtDataItemToMonitoringUnit( dataItem , ref monitoringUint , digitalState.bState0 );
                            }
                            else
                            {
                                ConvertRtDataItemToMonitoringUnit( dataItem , ref monitoringUint );
                            }
                        }
                    }
                    rtData.DatasChanged = true;
                }
            }
            if ( rtData.AqLjFile.Changed )
            {
                rtData.AqLjFile.Changed = false;
                if ( rtData.AqLjFile.Items != null )
                {
                    foreach ( Kj143AqLjItem dataItem in rtData.AqLjFile.Items )
                    {
                        var sId = GetSensorId( dataItem ) + sPostfix;

                        var monitoringUint = coalMineUnit.GetMonitoringUnit( sId );
                        if ( monitoringUint != null )
                        {
                            KJXXNToMonitoring.ConvertRtDataItemToMonitoringUnit( "正常" , dataItem.Value , dataItem.Time ,
                                                                                ref monitoringUint );
                        }
                    }
                    rtData.DatasChanged = true;
                }
            }
        }

        public static void ConvertRtDataItemToMonitoringUnit( Kj143AqSsItem dataItem , ref BaseMonitoringUnit monitoringUint )
        {
            ConvertRtDataItemToMonitoringUnit( dataItem , ref monitoringUint , true );
        }

        public static void ConvertRtDataItemToMonitoringUnit( Kj143AqSsItem dataItem , ref BaseMonitoringUnit monitoringUint , bool normalState )
        {
            string state = dataItem.State.ToString( );
            if ( monitoringUint.m_Modality == MonitoringUnitModality.Modalities.Digital )
            {
                if ( dataItem.State == Kj143SensorStates.正常 || dataItem.State == Kj143SensorStates.报警 )
                {
                    // 0 停， 1开
                    if ( normalState )
                    {
                        state = dataItem.Value < 1 ? "停" : "开";
                    }
                    else
                    {
                        state = dataItem.Value >= 1 ? "停" : "开";
                    }
                }
                else
                {
                    state = "中断";
                }
            }
            KJXXNToMonitoring.ConvertRtDataItemToMonitoringUnit( state , dataItem.Value , dataItem.Time , ref monitoringUint );
        }

        /// <summary>
        /// 自定义限值类型转换
        /// </summary>
        /// <param name="monitoringUint"></param>
        public static void ConvertLimitType( ref Kj143CommonItem devItem , ref string rawName , string m_strId )
        {
            LimitSetConfiguration limitSetConfig = LimitSetConfigurationManager.Config;
            foreach ( Eflong.Config.DevType type in limitSetConfig.DevTypes )
            {
                foreach ( string alias in type.AliasList )
                {
                    if ( devItem.Location.Contains( alias ) )
                    {
                        rawName = type.Name;
                        break;
                    }
                }
            }

            Dev curDev = limitSetConfig.Devs.FirstOrDefault( n => n.ID == m_strId );
            if ( curDev != null && !string.IsNullOrEmpty( curDev.DevType ) )
                rawName = curDev.DevType;
        }

        /// <summary>
        /// 单位转换
        /// </summary>
        /// <param name="devItem"></param>
        public static void ConvertUnit( ref Kj143CommonItem devItem )
        {
            LimitSetConfiguration limitSetConfig = LimitSetConfigurationManager.Config;
            string m_strUnit = devItem.Unit;
            Unit curUnit = limitSetConfig.Units.FirstOrDefault( n => n.From == m_strUnit );
            if ( curUnit != null && !string.IsNullOrEmpty( curUnit.To ) )
                devItem.Unit = curUnit.To;
        }

        /// <summary>
        /// 测点过滤
        /// </summary>
        /// <param name="devItem"></param>
        public static bool DataFilter( string devID , string location )
        {
            DataFilterConfiguration DataFilterConfig = DataFilterConfigurationManager.Config;
            if ( DataFilterConfig.DevID.BeginList.Any( n => devID.StartsWith( n.ToLower( ) ) ) )
                return true;
            if ( DataFilterConfig.DevID.ContainList.Any( n => devID.Contains( n.ToLower( ) ) ) )
                return true;
            if ( DataFilterConfig.DevID.EndList.Any( n => devID.EndsWith( n.ToLower( ) ) ) )
                return true;
            if ( DataFilterConfig.DevID.EqualList.Any( n => devID == n.ToLower( ) ) )
                return true;

            if ( DataFilterConfig.DevName.BeginList.Any( n => location.StartsWith( n.ToLower( ) ) ) )
                return true;
            if ( DataFilterConfig.DevName.ContainList.Any( n => location.Contains( n.ToLower( ) ) ) )
                return true;
            if ( DataFilterConfig.DevName.EndList.Any( n => location.EndsWith( n.ToLower( ) ) ) )
                return true;

            return false;
        }

        /// <summary>
        /// 自定义限值转换
        /// </summary>
        /// <param name="devItem"></param>
        /// <param name="monitoringUint"></param>
        public static void ConvertLimitSet( ref BaseMonitoringUnit monitoringUint )
        {
            LimitSetConfiguration limitSetConfig = LimitSetConfigurationManager.Config;

            if ( KWBridgeConfig.Instance.IsUseLimitSet )
            {
                string m_Type = monitoringUint.m_Type.ToString( );
                Eflong.Config.DevType curType = limitSetConfig.DevTypes.FirstOrDefault( n => n.Enabled && n.CustomSetEnabled && n.Name == m_Type );
                if ( curType != null )
                {
                    if ( !string.IsNullOrEmpty( curType.MeteLow ) )
                        monitoringUint.m_fLowerBound = StringToFloat( curType.MeteLow );
                    if ( !string.IsNullOrEmpty( curType.MeteUpper ) )
                        monitoringUint.m_fUpperBound = StringToFloat( curType.MeteUpper );
                    if ( !string.IsNullOrEmpty( curType.AlertLow ) )
                        monitoringUint.m_fLowerLimit = StringToFloat( curType.AlertLow );
                    if ( !string.IsNullOrEmpty( curType.AlertUpper ) )
                        monitoringUint.m_fUpperLimit = StringToFloat( curType.AlertUpper );
                }

                string m_strId = monitoringUint.m_strId;
                Dev curDev = limitSetConfig.Devs.FirstOrDefault( n => n.ID == m_strId );
                if ( curDev != null && curDev.CustomSetEnabled )
                {
                    if ( !string.IsNullOrEmpty( curDev.MeteLow ) )
                        monitoringUint.m_fLowerBound = StringToFloat( curDev.MeteLow );
                    if ( !string.IsNullOrEmpty( curDev.MeteUpper ) )
                        monitoringUint.m_fUpperBound = StringToFloat( curDev.MeteUpper );
                    if ( !string.IsNullOrEmpty( curDev.AlertLow ) )
                        monitoringUint.m_fLowerLimit = StringToFloat( curDev.AlertLow );
                    if ( !string.IsNullOrEmpty( curDev.AlertUpper ) )
                        monitoringUint.m_fUpperLimit = StringToFloat( curDev.AlertUpper );
                }
            }
        }

        /// <summary>
        /// 自定义限值类型转换
        /// </summary>
        /// <param name="monitoringUint"></param>
        public static void ConvertLimitType( ref BaseMonitoringUnit monitoringUint )
        {
            LimitSetConfiguration limitSetConfig = LimitSetConfigurationManager.Config;
            foreach ( Eflong.Config.DevType type in limitSetConfig.DevTypes )
            {
                foreach ( string alias in type.AliasList )
                {
                    if ( monitoringUint.m_strName.Contains( alias ) )
                    {
                        monitoringUint.m_Type = ( MonitoringUnitType.Types )Enum.Parse( typeof( MonitoringUnitType.Types ) , type.Name , true );
                        break;
                    }
                }
            }

            string m_strId = monitoringUint.m_strId;
            Dev curDev = limitSetConfig.Devs.FirstOrDefault( n => n.ID == m_strId );
            if ( curDev != null && !string.IsNullOrEmpty( curDev.DevType ) )
                monitoringUint.m_Type = ( MonitoringUnitType.Types )Enum.Parse( typeof( MonitoringUnitType.Types ) , curDev.DevType , true );
        }

        /// <summary>
        /// 单位转换
        /// </summary>
        /// <param name="devItem"></param>
        public static void ConvertUnit( ref BaseMonitoringUnit monitoringUint )
        {
            LimitSetConfiguration limitSetConfig = LimitSetConfigurationManager.Config;
            string m_strUnit = monitoringUint.m_strUnit;
            Unit curUnit = limitSetConfig.Units.FirstOrDefault( n => n.From == m_strUnit );
            if ( curUnit != null && !string.IsNullOrEmpty( curUnit.To ) )
                monitoringUint.m_strUnit = curUnit.To;
        }

        public static float StringToFloat( string sValue )
        {
            float fValue = 0.0f;
            if ( sValue != "" && sValue != null )
            {
                if ( float.TryParse( sValue , out fValue ) )
                {
                    return fValue;
                }
            }
            return fValue;
        }
    }
}